module ysyx_22040213_mul(
	input clk,
	input rst,
	input mul_valid,
	input flush,
//	input mulw,
	input [1:0] mul_signed,
	input [63:0] multiplicand,
	input [63:0] multiplier,
	output mul_ready,
	output reg out_valid,
	output reg [63:0] result_hi,
	output reg [63:0] result_lo
);
/* verilator lint_off UNUSED */
`define MUL_IDLE    2'b00
`define MUL_MULTING 2'b01
`define MUL_END     2'b10

wire signed [63:0] s_plicand = multiplicand;
wire signed [63:0] s_plier = multiplier;
reg [131:0]mul_x;
reg [66:0]mul_y;

wire[127:0] test_mul_result = mul_signed == 2'b11 ? s_plicand * s_plier : multiplicand * multiplier;
assign mul_ready = mul_state == `MUL_IDLE;

reg [131:0] mul_result;
wire [131:0] mul_res;
reg [1:0] mul_state;

always @(posedge clk)begin
  if(rst || flush)begin
   result_hi <= 64'b0;
   result_lo <= 64'b0;
   mul_result <= 132'b0;
   mul_state <= `MUL_IDLE;
   out_valid <= 1'b0;
   end else begin
    case(mul_state)
      `MUL_IDLE: begin
        if(mul_valid)begin
          mul_x <=  mul_signed[1] ? {{66'b0},{2{multiplicand[63]}},{multiplicand}} : {{68'b0},{multiplicand}};
          mul_y <= mul_signed[0] ? {{2{multiplier[63]}},{multiplier},{1'b0}} : {2'b0,{multiplier},{1'b0}};
	  mul_state <= `MUL_MULTING;
	  out_valid <= 1'b0;
	end else begin
	  mul_state <= `MUL_IDLE;
	  out_valid <= 1'b0;
	end
      end
      `MUL_MULTING: begin
        mul_x <= {mul_x[129:0],2'b0};
        mul_y <= {2'b0,{mul_y[66:2]}};
        mul_result <= mul_result + mul_res;
	if(mul_y == 67'b0)begin
	  mul_state <= `MUL_END;
	end
      end
      `MUL_END: begin
        result_hi <= mul_result[127:64];
	result_lo <= mul_result[63:0];
	out_valid <= 1'b1;
	mul_state <= `MUL_IDLE;
	mul_x <= 132'b0;
	mul_y <= 67'b0;
	mul_result <= 132'b0;
      end
      default: mul_state <= `MUL_IDLE;
    endcase
  end
end
ysyx_22040213_booth b1(
  .mul_x(mul_x),
  .mul_y(mul_y[2:0]),
  .mul_res(mul_res)
);
endmodule
